package com.yonyou.pmclouds.enterprise.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertMultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.enterprise.entity.EnterpriseRoleEnum;
import com.yonyou.pmclouds.enterprise.entity.EnterpriseVO;
import com.yonyou.pmclouds.enterprise.mapper.EnterpriseMapper;
import com.yonyou.pmclouds.enterprise.process.*;
import com.yonyou.pmclouds.enterprise.rmiitf.EnterpriseMaintain;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @Author chulf
 * @Date 2020/4/14
 * @Description
 **/
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = EnterpriseMaintain.class)
public class EnterpriseMaintainImpl implements EnterpriseMaintain {

    public static final String UPDATE_DATA_KEY = "updateData";
    public static final String ADD_DATA_KEY = "addData";
    public static final String DELETE_DATA_KEY = "deleteData";
    public static final int DR_FLAG = 1;
    public static final String[] UPDATE_FIELDS = {EnterpriseVO.NAME, EnterpriseVO.PLAN_AUTHORIZED_NUM, EnterpriseVO.REAL_AUTHORIZED_NUM, EnterpriseVO.ROLE, EnterpriseVO.PERSONNEL_NUM};

    @Autowired
    private EnterpriseMapper enterpriseMapper;
    @Autowired
    private AccountCehckBeforeProcess accountCehckBeforeProcess;
    @Autowired
    private InsertPersonnelAfterProcess insertPersonnelAfterProcess;
    @Autowired
    private InsertOrgAfterProcess insertOrgAfterProcess;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private DeletePersonAfterProcess deletePersonAfterProcess;
    @Autowired
    private DelCheckRefBeforeProcess delCheckRefBeforeProcess;

    @Autowired
    private InsertPersonnelByTeamAfterProcess insertPersonnelByTeamAfterProcess;

    @Override
    public EnterpriseVO saveEnterpriseVO(EnterpriseVO enterpriseVO) throws BusinessException {
        //将保存 新增和修改区分开
        if (StringUtils.isEmpty(enterpriseVO.getPkEnterprise())) {
            //新增数据
            SingleInsertBpTemplate<EnterpriseVO> bp = new SingleInsertBpTemplate<>(enterpriseMapper);
            bp.addBeforeProcessor(new AuditInfoInsertProcessor<>());

            //这里添加授权数控制
            //bp.addBeforeProcessor(accountCehckBeforeProcess);

            //这里添加 名字重复校验前置
            bp.addBeforeProcessor(new NameUniqueCheckBeforeProcess(enterpriseMapper));

            //唯一业主方校验
            bp.addBeforeProcessor(new EtpOrgUniqueCheckBeforeProcess(enterpriseMapper));

            //添加组织关系/人员信息
            bp.addAfterProcessor(insertOrgAfterProcess);
            bp.addAfterProcessor(insertPersonnelAfterProcess);

            bp.insert(enterpriseVO);
        } else {
            //修改数据
            SingleUpdateBpTemplate<EnterpriseVO> bp = new SingleUpdateBpTemplate<EnterpriseVO>(enterpriseMapper, UPDATE_FIELDS);
            bp.addBeforeProcessor(new AuditInfoUpdateProcessor<>());

            //添加授权数控制
            //bp.addBeforeProcessor(accountCehckBeforeProcess);
            ///这里添加 名字重复校验前置
            bp.addBeforeProcessor(new NameUniqueCheckBeforeProcess(enterpriseMapper));

            //唯一业主方校验
            bp.addBeforeProcessor(new EtpOrgUniqueCheckBeforeProcess(enterpriseMapper));
            //添加组织关系/人员信息
            bp.addAfterProcessor(insertOrgAfterProcess);
            bp.addAfterProcessor(insertPersonnelAfterProcess);
            bp.update(enterpriseVO);

        }

        return enterpriseVO;

    }

    @Override
    public void updateEnterprise(EnterpriseVO enterpriseVO) throws BusinessException {
        SingleUpdateBpTemplate<EnterpriseVO> bp = new SingleUpdateBpTemplate<EnterpriseVO>(enterpriseMapper, UPDATE_FIELDS);

        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<EnterpriseVO>());
        bp.update(enterpriseVO);
    }

    @Override
    public void deleteEnterpriseVOS(EnterpriseVO[] enterpriseVOS) throws BusinessException {
        /**
         *  这里先删除企业，再通过企业查询人员删除人员信息
         */

        MultiDeleteBpTemplate<EnterpriseVO> bp = new MultiDeleteBpTemplate<EnterpriseVO>(enterpriseMapper, true);

        //校验企业是否被引用
        bp.addBeforeProcessor(delCheckRefBeforeProcess);

        bp.addAfterProcessor(deletePersonAfterProcess);
        bp.delete(enterpriseVOS);
    }

    @Override
    public EnterpriseVO addEnterpriseByOrg(String pkOrg) throws BusinessException {

        //获的组织信息
        OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), pkOrg);

        //构建企业信息
        EnterpriseVO enterpriseVO = transEnterprise(organizationVO);
        saveEnterpriseVO(enterpriseVO);

        return enterpriseVO;
    }


    /**
     * @param enterpriseVOS
     * @return 将保存和修改数据区分
     */
    public Map<String, List<EnterpriseVO>> splitDatas(EnterpriseVO[] enterpriseVOS) {

        HashMap<String, List<EnterpriseVO>> splitData = new HashMap<>();
        for (EnterpriseVO enterpriseVO : enterpriseVOS) {
            if (StringUtils.isNotEmpty(enterpriseVO.getPkEnterprise())) {
                //主键不为空为修改和删除
                if (enterpriseVO.getDr() == 1) {
                    if (splitData.get(DELETE_DATA_KEY) == null)
                        splitData.put(DELETE_DATA_KEY, new ArrayList<EnterpriseVO>());
                    splitData.get(DELETE_DATA_KEY).add(enterpriseVO);

                } else {
                    if (splitData.get(UPDATE_DATA_KEY) == null)
                        splitData.put(UPDATE_DATA_KEY, new ArrayList<EnterpriseVO>());
                    splitData.get(UPDATE_DATA_KEY).add(enterpriseVO);
                }
            } else {
                if (splitData.get(ADD_DATA_KEY) == null)
                    splitData.put(ADD_DATA_KEY, new ArrayList<EnterpriseVO>());
                splitData.get(ADD_DATA_KEY).add(enterpriseVO);
            }
        }

        return splitData;
    }

    /**
     * 通过组织构建企业信息
     *
     * @param organizationVO
     * @return
     */
    private EnterpriseVO transEnterprise(OrganizationVO organizationVO) {

        EnterpriseVO enterpriseVO = new EnterpriseVO();
        enterpriseVO.setName(organizationVO.getSname());
        enterpriseVO.setPkTenant(organizationVO.getPkTenant());
        enterpriseVO.setPersonnelNum(0);
        enterpriseVO.setRealAuthorizedNum(0);
        enterpriseVO.setPlanAuthorizedNum(0);
        enterpriseVO.setRole(EnterpriseRoleEnum.PROPRIETOR.getValue().byteValue());
        enterpriseVO.setPkOrgs(Arrays.asList(new String[]{organizationVO.getPkSrc()}));
        enterpriseVO.setPkTenant(RuntimeEnvironment.getTenantId());

        return enterpriseVO;
    }

    @Override
    public EnterpriseVO[] insertEnterprises(EnterpriseVO[] enterpriseVOS) throws BusinessException {
        if(enterpriseVOS == null || enterpriseVOS.length <= 0){
            return new EnterpriseVO[0];
        }

        return insertEnterpriseBatch(enterpriseVOS);
    }

    private EnterpriseVO[] insertEnterpriseBatch(EnterpriseVO[] enterpriseVOS) throws BusinessException{
        MultiInsertBpTemplate<EnterpriseVO> insertBpTemplate = new MultiInsertBpTemplate<>(enterpriseMapper);

        insertBpTemplate.addBeforeProcessor(new AuditInfoInsertMultiProcessor<>());
        insertBpTemplate.addBeforeProcessor(new NameUniqueCheckBeforeProcess(enterpriseMapper));
        insertBpTemplate.addBeforeProcessor(new EtpOrgUniqueCheckBeforeProcess(enterpriseMapper));

        insertBpTemplate.addAfterProcessor(insertOrgAfterProcess);
        insertBpTemplate.addAfterProcessor(insertPersonnelAfterProcess);

        return insertBpTemplate.insert(enterpriseVOS);
    }

    @Override
    public EnterpriseVO[] insertEnterprisesByTeam(EnterpriseVO[] enterpriseVOS) throws BusinessException {
        MultiInsertBpTemplate<EnterpriseVO> insertBpTemplate = new MultiInsertBpTemplate<>(enterpriseMapper, false);

        insertBpTemplate.addBeforeProcessor(new AuditInfoInsertMultiProcessor<>());
        insertBpTemplate.addBeforeProcessor(new NameUniqueCheckBeforeProcess(enterpriseMapper));
        insertBpTemplate.addBeforeProcessor(new EtpOrgUniqueCheckBeforeProcess(enterpriseMapper));

        insertBpTemplate.addAfterProcessor(insertOrgAfterProcess);
        insertBpTemplate.addAfterProcessor(insertPersonnelByTeamAfterProcess);

        return insertBpTemplate.insert(enterpriseVOS);
    }
}
